home *** CD-ROM | disk | FTP | other *** search
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- NNNNAAAAMMMMEEEE
- pciio_pio: pciio_pio_addr, pciio_piotrans_addr, pciio_piomap_alloc,
- pciio_piomap_addr, pciio_piomap_done, pciio_piomap_free,
- pciio_piospace_alloc, pciio_piospace_free - programmed I/O to PCI bus
-
- SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
- ####iiiinnnncccclllluuuuddddeeee <<<<ssssyyyyssss////PPPPCCCCIIII////ppppcccciiiiiiiioooo....hhhh>>>>
-
- ccccaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ppppiiiioooo____aaaaddddddddrrrr((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- ppppcccciiiiiiiioooo____ssssppppaaaacccceeee____tttt _s_p_a_c_e,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____tttt ****_m_a_p_p,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- ccccaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ppppiiiioooottttrrrraaaannnnssss____aaaaddddddddrrrr((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- ppppcccciiiiiiiioooo____ssssppppaaaacccceeee____tttt _s_p_a_c_e,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____tttt
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____aaaalllllllloooocccc((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- ppppcccciiiiiiiioooo____ssssppppaaaacccceeee____tttt _s_p_a_c_e,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- ssssiiiizzzzeeee____tttt _m_a_x,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- ccccaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____aaaaddddddddrrrr((((
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____tttt _m_a_p,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e))));;;;
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____ddddoooonnnneeee((((ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____tttt _m_a_p))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____ffffrrrreeeeeeee((((ppppcccciiiiiiiioooo____ppppiiiioooommmmaaaapppp____tttt _m_a_p))))
-
- iiiiooooppppaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ppppiiiioooossssppppaaaacccceeee____aaaalllllllloooocccc((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- ppppcccciiiiiiiioooo____ssssppppaaaacccceeee____tttt _s_p_a_c_e,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- ssssiiiizzzzeeee____tttt _a_l_i_g_n))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ppppiiiioooossssppppaaaacccceeee____ffffrrrreeeeeeee((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ppppcccciiiiiiiioooo____ssssppppaaaacccceeee____tttt _s_p_a_c_e,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e))))
-
- AAAArrrrgggguuuummmmeeeennnnttttssss
- _a_d_d_r The offset within the given _s_p_a_c_e.
-
- _a_l_i_g_n A desired alignment in PCI address space.
-
- _d_e_s_c A device descriptor, usually zero.
-
- _f_l_a_g_s Flags describing the use of the PIO map.
-
- _m_a_x The maximum size within _s_p_a_c_e to be mapped at any one time.
-
- _m_a_p The map address returned by _p_c_i_i_o__p_i_o_m_a_p__a_l_l_o_c().
-
- _m_a_p_p A pointer variable to receive the address of an allocated map.
-
- _s_i_z_e The size of the region to be mapped.
-
- _s_p_a_c_e Specifies the target PCI address space.
-
- _v_h_d_l The PCI connection point as given to the _a_t_t_a_c_h() entry point.
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- When a device driver wishes to use Programmed I/O (PIO) to communicate
- with a device, the system needs to have a chance to set up any
- appropriate mapping registers. The work to be done varies with the
- available hardware and with the version of IRIX. The functions described
- here provide an abstract interface to the creation of PIO mapping
- objects, an interface that is consistent across most hardware. These
- functions always do the least possible work given the available hardware.
-
- There are two models for setting up a PIO map, one simple but fallible,
- and one more general. In both models, the final goal is to retrieve a
- physical address that, when used as the operand of a store or fetch, will
- access a word in PCI bus address space rather than in CPU memory address
- space.
-
- SSSSiiiimmmmpppplllleeee MMMMooooddddeeeellll
- The simple model provides permanent mappings through fixed mapping
- resources that may or may not exist in a given system at a given time.
- _p_c_i_i_o__p_i_o_t_r_a_n_s__a_d_d_r() attempts to use shared hardware resources to
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- construct a physical address that, whenever used, routes the transaction
- to the proper target on the PCI bus. This is not always possible. When
- it is not, the function returns NULL.
-
- When it works, _p_c_i_i_o__p_i_o_t_r_a_n_s__a_d_d_r() allows the driver to do PIO with the
- fewest complications. Typically _p_c_i_i_o__p_i_o_t_r_a_n_s__a_d_d_r() always succeeds in
- some platforms, and always fails in others. However, a driver that uses
- it should be coded as if it could succeed or fail alternately in the same
- system (which it could).
-
- GGGGeeeennnneeeerrrraaaallll MMMMooooddddeeeellll
- It is not always possible to establish a PIO mapping using common shared
- system resources, so the concept of a PIO channel that preallocates
- scarce mapping resources is provided.
-
- Such a channel is allocated using _p_c_i_i_o__p_i_o_m_a_p__a_l_l_o_c(), which is given
- the limits of the region that will be mapped, and the maximum size to be
- mapped at any time within that region. The model assumes that many
- channels may be created, but that not all channels will be actively in
- use at any time.
-
- _p_c_i_i_o__p_i_o_m_a_p__a_d_d_r() is used to actually establish the proper mappings for
- a PIO target. Given the offset within the target address space and the
- size of the region for PIO, it returns the base address to be used for
- accessing that region.
-
- After all PIO transactions to that region are executed,
- _p_c_i_i_o__p_i_o_m_a_p__d_o_n_e() should be called to idle any mapping hardware and
- possibly to flush out any pipes or buffers along the path that might do
- unexpected things when mapping registers are modified.
-
- Later, _p_c_i_i_o__p_i_o_m_a_p__a_d_d_r() can again be called, specifying the same or a
- new target area.
-
- When a driver is completely finished with a PIO channel -- either because
- the channel is used only for initialization of the device, or because the
- device or the driver is being shut down -- the PIO channel resources
- should be released using _p_c_i_i_o__p_i_o_m_a_p__f_r_e_e().
-
- UUUUttttiiiilllliiiittttyyyy FFFFuuuunnnnccccttttiiiioooonnnnssss
- _p_c_i_i_o__p_i_o__a_d_d_r() is a wrapper function that calls _p_c_i_i_o__p_i_o_t_r_a_n_s__a_d_d_r()
- to establish a mapping. If that call fails, it then allocates a map
- using _p_c_i_i_o__p_i_o_m_a_p__a_l_l_o_c() (or uses the preallocated map passed in via
- the _m_a_p_p pointer), and fills it in using _p_c_i_i_o__p_i_o_m_a_p__a_d_d_r(), returning
- the resulting piomap via the map pointer _m_a_p_p. This function
- encapsulates the common two-step process of attempting a simple address
- translation and falling back to the more general process in the event the
- simple approach fails.
-
- _p_c_i_i_o__p_i_o_s_p_a_c_e__a_l_l_o_c() can be used to find a block of PCI address space
- that nobody else is using, which can then be used for whatever the device
- and driver wish to use it for. The PCI infrastructure preallocates PCI
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- address space regions based on the device configuration BASE registers at
- the time the bus is discovered. As a result this function is needed only
- to manage a device that does not completely declare its address space
- usage in its hardware configuration registers.
-
- _p_c_i_i_o__p_i_o_s_p_a_c_e__f_r_e_e() is used to release any allocations that were
- previously made by _p_c_i_i_o__p_i_o_s_p_a_c_e__a_l_l_o_c().
-
- SSSSppppeeeecccciiiiffffyyyyiiiinnnngggg PPPPCCCCIIII AAAAddddddddrrrreeeessssssss SSSSppppaaaacccceeeessss
- The _s_p_a_c_e parameter takes on of the following values:
-
- PCIIO_SPACE_WIN(n)
- specifies one of the regions on the PCI bus decoded by the
- PCI card's BASE registers. The address specified is the
- offset within the decoded area, and the entire PIO region
- must fit within the decoded area.
-
- PCIIO_SPACE_CFG
- requests a pointer handle that can be used to access the
- configuration space for the card, via the _p_c_i_i_o__c_o_n_f_i_g__g_e_t()
- and _p_c_i_i_o__c_o_n_f_i_g__s_e_t() functions documented in
- pciio_config(D3).
-
- Other space types are rarely needed but can be used:
-
- PCIIO_SPACE_IO
- requests a mapping into somewhere in the PCI bus I/O address
- space.
-
- PCIIO_SPACE_MEM
- requests a mapping into somewhere in the PCI bus Memory
- space. Since PCI bus address space is preallocated by the
- kernel, this is a dangerous function to use.
-
- PPPPIIIIOOOO AAAAttttttttrrrriiiibbbbuuuutttteeee FFFFllllaaaaggggssss
- The _f_l_a_g_s argument specifies some uses of the map.
-
- PCIIO_FIXED states that all translations will be done using fixed shared
- resources; the results of those translations will remain
- valid permanently, even if the map resource is subsequently
- used to obtain additional mappings.
-
- PCIIO_NOSLEEP
- requests that any resources that are needed from the system
- are allocated without sleeping. If any resource allocation
- would have required the infrastructure to sleep, the service
- call will return a failure code.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
- Here is a contrived example of how one might initialize a very strange
- PCI card. It is not clear that this would be the best way to do it, but
- it does give an example of the relationship between the various
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- functions.
-
- pcifoo_attach(vertex_hdl_t vhdl)
- {
- unsigned *cfgspace;
- struct pcifoo_devregs *devregs;
- pciio_piomap_t pmap;
- pciio_piomap_t cmap;
- struct pcifoo_chan_config *tune;
- ...
- /* Get the configuration space base
- * pointer.
- */
- cfgspace = pciio_piotrans_addr
- (vhdl, 0, PCIIO_SPACE_CFG, 0, 256, 0);
- if (cfgspace == NULL) {
- cmn_err(CE_ALERT,
- "pcifoo_attach: pciio_piotrans_addr failed");
- return -1;
- }
- /* Get a pointer we can use for PIO to our
- * device's control registers. This call
- * attempts to use fixed shared resources,
- * but will allocate unshared mapping resources
- * if required.
- */
- devregs = pciio_pio_addr
- (vhdl, 0,
- PCIIO_SPACE_WIN(0), 0,
- sizeof (struct pcifoo_devregs),
- &pmap, 0);
- if (devregs == NULL) {
- cmn_err(CE_ALERT,
- "pcifoo_attach: pciio_pio_addr failed");
- return -1;
- }
- /* save cfgspace and devregs for use;
- * save pmap for pciio_dmamap_free
- * call if/when we are unregistered.
- */
- ...
- /* pretend our "channel" space is too big
- * to successfully map with piotrans, so
- * we have to use piomap, and that it is
- * too big for us to get it in one call
- * to piomap_addr.
- */
- cmap = pciio_piomap_alloc(vhdl, 0,
- PCIIO_SPACE_WIN(2), 0, CHAN_SEP * CHANS,
- sizeof (struct pcifoo_chan_config), 0);
- for (chan = 0; chan < chans; ++chan) {
- tune = (struct pcifoo_chan_config *)
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333)))) ppppcccciiiiiiiioooo____ppppiiiioooo((((DDDD3333))))
-
-
-
- pciio_piomap_addr(cmap, CHAN_SEP * chan,
- sizeof (struct pcifoo_chan_config));
- /* now fiddle with this particular channel */
- tune->chan = chan + 2;
- tune->volume = 5;
- tune->balance = 0;
- pciio_piomap_done(cmap);
- }
- pciio_piomap_free(cmap);
- ...
- }
-
-
- NNNNOOOOTTTTEEEESSSS
- Do not point the _m_a_p_p parameter to the _p_c_i_i_o__p_i_o__a_d_d_r() function at your
- only copy of a map pointer, since it will write a NULL through this
- pointer when direct translations work.
-
- It is not necessary to separately establish mappings for each individual
- PIO target register. It is customary and more efficient to use a single
- mapping to cover the entire register set of a device.
-
- SSSSEEEEEEEE AAAALLLLSSSSOOOO
- pciio(D3), pciio_config(D3), pciio_dma(D3), pciio_error(D3),
- pciio_get(D3), pciio_intr(D3).
-
- DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
- _p_c_i_i_o__p_i_o_t_r_a_n_s__a_d_d_r() returns a null pointer when shared (fixed)
- resources can not be used to construct a valid physical address that maps
- to the desired range of PCI addresses.
-
- _p_c_i_i_o__p_i_o__a_d_d_r() returns a null pointer when the target PCI address can
- not be mapped either with shared (fixed) resources, or with unshared
- mapping resources. If this happens, and the object being mapped is
- large, it might be possible to set up mappings to smaller regions of the
- target space.
-
- _p_c_i_i_o__p_i_o_m_a_p__a_l_l_o_c() returns a null pointer when resources can not be
- allocated to establish PIO mappings to the described region, or if the
- function parameters are inconsistent.
-
- _p_c_i_i_o__p_i_o_m_a_p__a_d_d_r() returns a null pointer when the specified target
- address can not be mapped using the specified PIO channel. This would
- usually be due to specifying a target block that is outside the
- previously specified target area or is larger than the previously
- specified maximum mapping size. It may also return a null pointer if the
- PIO channel is currently in use and has not been marked idle by a
- _p_c_i_i_o__p_i_o_m_a_p__d_o_n_e() call.
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-